/**
 * Copyright (C) 2008 aileron.cc
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package cc.aileron.wsgi.filedownload;

import static cc.aileron.wsgi.navigation.WsgiNavigation.State.End;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.HttpURLConnection;

import javax.servlet.http.HttpServletResponse;

import cc.aileron.commons.accessor.PojoAccessorFactory;
import cc.aileron.wsgi.WsgiProcess;
import cc.aileron.wsgi.context.WsgiProcessContext;
import cc.aileron.wsgi.navigation.WsgiNavigation;

import com.google.inject.Inject;

/**
 * WsgiFileDownloadProcessProvider impl
 * 
 * @author aileron
 * 
 */
public class WsgiFileDownloadProcessProviderImpl implements
        WsgiFileDownloadProcessProvider
{

    /*
     * (非 Javadoc)
     * 
     * @see
     * cc.aileron.wsgi.filedownload.WsgiFileDownloadProcessProvider#get(java
     * .lang.String)
     */
    @Override
    public <T> WsgiProcess<T> get(final String propertieName)
    {
        return new WsgiProcess<T>()
        {
            @Override
            public WsgiNavigation doProcess(final T t) throws Exception
            {
                final File file = (File) factory.accessor(t).getObject(
                        propertieName);
                final HttpServletResponse response = context.getResponse();
                response.setContentType("application/octet-stream");
                response.setHeader("Content-disposition",
                        "attachment; filename=\"" + file.getName() + "\"");
                response.setContentLength((int) file.length());
                response.setHeader("Expiresponse", "0");
                response.setHeader("Cache-Control",
                        "must-revalidate, post-check=0,pre-check=0");
                response.setHeader("Pragma", "private");

                BufferedInputStream in = null;
                BufferedOutputStream out = null;
                try
                {
                    in = new BufferedInputStream(new FileInputStream(file));
                    out = new BufferedOutputStream(response.getOutputStream());
                    final byte buf[] = new byte[1024];
                    int len;
                    while ((len = in.read(buf)) != -1)
                    {
                        out.write(buf, 0, len);
                    }
                }
                catch (final Exception e)
                {
                    response.reset();
                    response.sendError(HttpURLConnection.HTTP_INTERNAL_ERROR, e
                            .toString());
                }
                finally
                {
                    if (in != null)
                    {
                        in.close();
                    }
                    if (out != null)
                    {
                        out.flush();
                        out.close();
                    }
                }

                return End.navigation();
            }
        };
    }

    /**
     * @param factory
     * @param context
     */
    @Inject
    public WsgiFileDownloadProcessProviderImpl(
            final PojoAccessorFactory factory, final WsgiProcessContext context)
    {
        this.factory = factory;
        this.context = context;
    }

    /**
     * context
     */
    final WsgiProcessContext context;

    /**
     * factory
     */
    final PojoAccessorFactory factory;
}
